#include "mailhead.h"
#include "buffer.h"
#include "received.h"


MAILHEAD*  
mailhead_new()
{
    MAILHEAD*  head;

    head = (MAILHEAD*)emalloc(sizeof(MAILHEAD));
    if (NULL == head)
        return NULL;

    memset(head, 0, sizeof(MAILHEAD));
        
    return head;
}


void        
mailhead_delete(MAILHEAD*  head)
{    
    if (NULL == head)
        return;

    mailhead_clear(head);
    
    if (NULL != head->Others) {
        g_hash_table_destroy(head->Others);
    }
    efree(head);
}
   
void headrecv_delete (gpointer data, gpointer user_data)
{
 	 char *recv = (char *)data;
 	 efree(recv);
}

void        
mailhead_clear(MAILHEAD*  head)
{
    if (NULL == head)
        return;
    
    SAFE_FREE(head->From)
    SAFE_FREE(head->Sender)
    SAFE_FREE(head->ReplyTo)
    SAFE_FREE(head->To)
    SAFE_FREE(head->Cc)
    SAFE_FREE(head->Bcc)
    SAFE_FREE(head->MessageId)
    SAFE_FREE(head->Date)
    SAFE_FREE(head->Subject)
   
    if (NULL != head->Received)
    {
        // 是不是应该先释放list里每一项占用的内存？ 
        g_slist_foreach(head->Received, headrecv_delete, NULL);
        g_slist_free(head->Received);
        head->Received = NULL;
    }   

    if (NULL != head->Others)
    {
        // 删除hashtable也要注意里面的key和value的释放 
        g_hash_table_remove_all(head->Others); 
        //head->Others = NULL;
    }

}

void 
mailvalue_free(void* data)
{
    efree(data);
}

int         
mailhead_set(void *hd, char* key, char* value, int vlen)
{
    MAILHEAD    *head = hd;
    char        *tmp, *val;
    int         size = 0;

    if (NULL == head)
        return -1;

    if (NULL == key)
        return -2;

    if (NULL == value)
        return -3;

    if (0 >= vlen) 
        return -4;
   
    //mailhead_clear(head);
    //INFO("set key: %s value len: %d\n", key, vlen);
    switch(key[0])
    {
    case 'b':
        if (strcmp(key, "bcc") == 0) {
            head->Bcc = xstrappend(head->Bcc, value, vlen);
            return 0;
        }
        break;
    case 'c':
        if (0 == strcmp(key, "cc")) {
            head->Cc = xstrappend(head->Cc, value, vlen);        
            return 0;
        }
        break;
    case 'd':
        if (0 == strcmp(key, "date")) {
            head->Date = xstrappend(head->Date, value, vlen);
            return 0;
        }
        break;
    case 'f':
        if ( 0 == strcmp(key, "from")) {
            head->From = xstrappend(head->From, value, vlen);
            return 0;
        }
        break;    
    case 'r':
        if (0 == strcmp(key, "reply-to")) {
 	        head->ReplyTo = xstrappend(head->ReplyTo, value, vlen);
            return 0;
		}else if (0 == strcmp(key, "received")) {
            head->Received = g_slist_append(head->Received, xstrndup(value, vlen));
            return 0;
		}
        break;
    case 's':
	    if (0 == strcmp(key, "sender")) {
            head->Sender = xstrappend(head->Sender, value, vlen);
            return 0;
		}else if (0 == strcmp(key, "subject")) {
            head->Subject = xstrappend(head->Subject, value, vlen);
            return 0;
		}
        break;
    case 't':
	    if (0 == strcmp(key, "to")) {
            head->To = xstrappend(head->To, value, vlen);
            return 0;
		}
        break;
    default:
        break;
    }
    if (NULL == head->Others)
    {
        head->Others = g_hash_table_new_full(g_str_hash, g_str_equal, mailvalue_free, mailvalue_free);
        if (NULL == head->Others)
            return -5;
    }
    // 这里的value应该是还指定了长度的 
    tmp = g_hash_table_lookup(head->Others, key);
    if (NULL == tmp) {
        g_hash_table_insert(head->Others, xstrdup(key), xstrndup(value, vlen));
    }else{
        val = xstrappend_nofree(tmp, value, vlen); 
        if (NULL != val) { 
            g_hash_table_insert(head->Others, xstrdup(key), val);
        }
    }

    return 0;
}


int         
mailhead_parse(MAILHEAD* head, BUFFER *buf)
{
	char	*start;
	int		len, ret;
    int     split_error = 0;

    if (NULL == head) {
        ERROR("mailhead_parse: NULL == head\n");
        return -1;
    }
    if (NULL == buf) {
        ERROR("mailhead_parse: NULL == buf\n");
        return -2;
    }
    
    while (1) {
        ret = buf_getfield(buf, &start, &len);
        //INFO("buf_getfield: %d\n", ret);
        if (ret <= 0) {
            INFO("parse at end of file.\n");
            break;
        }
        if (ret == 1 || (ret == 2 && start[0] == '\r')) { //长度只有1的话，一个是只有\n, 是2的话也有可能是\r\n
            head->endpos = buf_file_pos(buf) - ret;
            INFO("found endpos\n");
            break;
        }
        /*    
        {
            int i;
            for (i = 0; i< len; i++) {
                printf("%c", start[i]);
            }
            printf("\n");
        }
        */
        ret = fields_split(start, len, head, mailhead_set);
        if (ret == -3) {
            split_error++;
            INFO("not found : , error: %d\n", split_error);
        }
        if (split_error >= 3) {
            //连续3行都没有发现:, 在信件头中是不可能的, 必定是信件格式有问题
            head->endpos = buf_file_pos(buf);
            INFO("error 3 , endpos: %d\n", head->endpos);
            return 1;
        }
    }

    return 0;
}

void 
mailheadother_print(gpointer key, gpointer val, gpointer user)
{
    printf("%s: %s\n", (char*)key, (char*)val);
}


void 
mailhead_print(MAILHEAD *head)
{
    GSList  *item;
    if (NULL == head)
        return;
    printf("From:%s\nSender:%s\nReplyTo:%s\nTo:%s\nCc:%s\nBcc:%s\nMessageId:%s\nDate:%s\nSubject:%s\n",
           head->From, head->Sender, head->ReplyTo, head->To, head->Cc, head->Bcc, head->MessageId, head->Date, head->Subject);
    printf("endpos: %d\n", head->endpos);
    item = head->Received; 
    while (item) {
        //received_print(item->data);
        printf("received: %s\n", (char*)item->data);
        item = g_slist_next(item);
    }
    if (NULL != head->Others)
        g_hash_table_foreach(head->Others, mailheadother_print, NULL);

}

int 
mailhead_string(MAILHEAD *head, char *save, int slen)
{
    if (NULL == head)
        return -1;

    return 0;
}


